/*********************************************************************
 * Copyright (C) 2004 Andrew Khan
 * <p>
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * <p>
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * <p>
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ***************************************************************************/

package jxl.biff;

import jxl.WorkbookSettings;
import jxl.biff.formula.ExternalSheet;
import jxl.biff.formula.FormulaException;
import jxl.common.Assert;
import jxl.common.Logger;
import jxl.read.biff.Record;

/**
 * Data validity settings.   Contains an individual Data validation (DV).  
 * All the computationa work is delegated to the DVParser object
 */
public class DataValiditySettingsRecord extends WritableRecordData {
    /**
     * The logger
     */
    private static Logger logger =
            Logger.getLogger(DataValiditySettingsRecord.class);

    /**
     * The binary data
     */
    private byte[] data;

    /**
     * The reader
     */
    private DVParser dvParser;

    /**
     * Handle to the workbook
     */
    private WorkbookMethods workbook;

    /**
     * Handle to the externalSheet
     */
    private ExternalSheet externalSheet;

    /**
     * Handle to the workbook settings
     */
    private WorkbookSettings workbookSettings;

    /**
     * Handle to the data validation record
     */
    private DataValidation dataValidation;

    /**
     * Constructor
     */
    public DataValiditySettingsRecord(Record t,
                                      ExternalSheet es,
                                      WorkbookMethods wm,
                                      WorkbookSettings ws) {
        super(t);

        data = t.getData();
        externalSheet = es;
        workbook = wm;
        workbookSettings = ws;
    }

    /**
     * Copy constructor
     */
    DataValiditySettingsRecord(DataValiditySettingsRecord dvsr) {
        super(Type.DV);

        data = dvsr.getData();
    }

    /**
     * Constructor used when copying sheets
     *
     * @param dvsr the record copied from a writable sheet
     */
    DataValiditySettingsRecord(DataValiditySettingsRecord dvsr,
                               ExternalSheet es,
                               WorkbookMethods w,
                               WorkbookSettings ws) {
        super(Type.DV);

        workbook = w;
        externalSheet = es;
        workbookSettings = ws;

        Assert.verify(w != null);
        Assert.verify(es != null);

        data = new byte[dvsr.data.length];
        System.arraycopy(dvsr.data, 0, data, 0, data.length);
    }

    /**
     * Constructor called when the API creates a writable data validation
     *
     * @param dvsr the record copied from a writable sheet
     */
    public DataValiditySettingsRecord(DVParser dvp) {
        super(Type.DV);
        dvParser = dvp;
    }

    /**
     * Initializes the dvParser
     */
    private void initialize() {
        if (dvParser == null) {
            dvParser = new DVParser(data, externalSheet,
                    workbook, workbookSettings);
        }
    }

    /**
     * Retrieves the data for output to binary file
     *
     * @return the data to be written
     */
    public byte[] getData() {
        if (dvParser == null) {
            return data;
        }

        return dvParser.getData();
    }

    /**
     * Inserts a row
     *
     * @param row the row to insert
     */
    public void insertRow(int row) {
        if (dvParser == null) {
            initialize();
        }

        dvParser.insertRow(row);
    }

    /**
     * Removes a row
     *
     * @param row the row to insert
     */
    public void removeRow(int row) {
        if (dvParser == null) {
            initialize();
        }

        dvParser.removeRow(row);
    }

    /**
     * Inserts a row
     *
     * @param col the row to insert
     */
    public void insertColumn(int col) {
        if (dvParser == null) {
            initialize();
        }

        dvParser.insertColumn(col);
    }

    /**
     * Removes a column
     *
     * @param col the row to insert
     */
    public void removeColumn(int col) {
        if (dvParser == null) {
            initialize();
        }

        dvParser.removeColumn(col);
    }

    /**
     * Accessor for first column
     *
     * @return the first column
     */
    public int getFirstColumn() {
        if (dvParser == null) {
            initialize();
        }

        return dvParser.getFirstColumn();
    }

    /**
     * Accessor for the last column
     *
     * @return the last column
     */
    public int getLastColumn() {
        if (dvParser == null) {
            initialize();
        }

        return dvParser.getLastColumn();
    }

    /**
     * Accessor for first row
     *
     * @return the first row
     */
    public int getFirstRow() {
        if (dvParser == null) {
            initialize();
        }

        return dvParser.getFirstRow();
    }

    /**
     * Accessor for the last row
     *
     * @return the last row
     */
    public int getLastRow() {
        if (dvParser == null) {
            initialize();
        }

        return dvParser.getLastRow();
    }

    /**
     * Sets the handle to the data validation record
     *
     * @param dv the data validation
     */
    void setDataValidation(DataValidation dv) {
        dataValidation = dv;
    }

    /**
     * Gets the DVParser.  This is used when doing a deep copy of cells
     * on the writable side of things
     */
    DVParser getDVParser() {
        return dvParser;
    }

    public String getValidationFormula() {
        try {
            if (dvParser == null) {
                initialize();
            }

            return dvParser.getValidationFormula();
        } catch (FormulaException e) {
            logger.warn("Cannot read drop down range " + e.getMessage());
            return "";
        }
    }
}
